package com.seanliao.nav.util;

import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.seanliao.nav.properties.LoginProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * token工具
 */
@Slf4j
@Component
public class TokenUtil {

    private static LoginProperties loginProperties;

    public TokenUtil(LoginProperties loginProperties) {
        log.info("init TokenUtil");
        TokenUtil.loginProperties = loginProperties;
    }

    /**
     * 生成jwt
     */
    public static String token(long userId) {
        int effectiveTime = Math.toIntExact(loginProperties.getEffectiveTime().getSeconds());
        return token(userId, effectiveTime);
    }


    /**
     * 生成临时jwt
     */
    public static String tempToken(long userId) {
        int effectiveTime = Math.toIntExact(loginProperties.getTempTime().getSeconds());
        return token(userId, effectiveTime);
    }

    /**
     * @param userId
     * @param effectiveTime 有效时长，单位：秒
     * @return
     */
    public static String token(long userId, int effectiveTime) {
        JWTSigner jwtSigner = JWTSignerUtil.createSigner("HS256", loginProperties.getJwtKey().getBytes());
        return JWT.create()
                .setExpiresAt(DateUtil.date().offset(DateField.SECOND, effectiveTime))
                .setPayload("user_id", userId)
                .setSigner(jwtSigner)
                .sign();
    }

    /**
     * 检查jwt
     */
    public static boolean check(String token) {
        try {
            JWTSigner jwtSigner = JWTSignerUtil.createSigner("HS256", loginProperties.getJwtKey().getBytes());
            JWTValidator validator = JWTValidator.of(token);
            // 检查签名
            validator.validateAlgorithm(jwtSigner);
            // 检查过期
            validator.validateDate(DateUtil.date());
        } catch (ValidateException e) {
            return false;
        }
        return true;
    }

    /**
     * 解析jwt的用户id
     */
    public static long parseUserId(String token) {
        JWT jwt = JWTUtil.parseToken(token);
        return ((NumberWithFormat) jwt.getPayload("user_id")).longValue();
    }

}
